package com.gonsin.gmessage.logic.render;

import com.github.xiaoymin.knife4j.core.extend.OpenApiExtendMarkdownChildren;
import com.github.xiaoymin.knife4j.core.extend.OpenApiExtendMarkdownFile;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class RenderManager implements InitializingBean {


    private MarkdownRender markdownRender;

    private List<OpenApiExtendMarkdownChildren> markdowns;

    private OpenApiExtendMarkdownFile markdownFile;

    private Map<String, OpenApiExtendMarkdownChildren> markdownContentMap;


    /**
     * 文档生成入口
     * @param note
     * @param message
     */
    public void render(String note, MessageDescription message) {

        OpenApiExtendMarkdownChildren mk = markdownContentMap.get(note);
        if(mk == null){
            mk = new OpenApiExtendMarkdownChildren();
            mk.setTitle(message.getNote());
            mk.setContent("");
            markdowns.add(mk);
            markdownContentMap.put(note, mk);
            mk.setContent(markdownRender.render(message));
            return;
        }
        mk.setContent(mk.getContent() + "\n" + markdownRender.render(message));
    }

    /**
     * 代码生成的协议
     */
    public OpenApiExtendMarkdownFile getMarkdowns() {
        return markdownFile;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.markdownRender = new MarkdownRender();
        this.markdowns = new ArrayList<>();
        this.markdownFile = new OpenApiExtendMarkdownFile();
        this.markdownFile.setChildren(this.markdowns);
        this.markdownFile.setName("对外消息");
        this.markdownContentMap = new HashMap<>();

        // 获取resource里的markdown资源
        OpenApiExtendMarkdownChildren mqtt = new OpenApiExtendMarkdownChildren();
        mqtt.setContent(MQTT_CONTENT);
        mqtt.setTitle("对接说明");
        this.markdownFile.getChildren().add(mqtt);

//        OpenApiExtendMarkdownChildren websocket = new OpenApiExtendMarkdownChildren();
////        websocket.setContent(new String(CommonUtils.readBytes(ResourceUtils.getFile("classpath:gmessage/websocket.md")), StandardCharsets.UTF_8));
//        websocket.setContent(WEBSOCKET_CONTENT);
//        websocket.setTitle("对接说明 - WEBSOCKET");
//        this.markdownFile.getChildren().add(websocket);
    }


    public static final String MQTT_CONTENT = "# 对接说明\n" +
            "\n" +
            "*协议版本号：v1.0.0*\n" +
            "\n" +
            "## 前言\n" +
            "\n" +
            "会务系统对外消息使用MQTT协议实现，自有设备或者第三方设备都可以以MQTT客户端的方式连接到会务服务器1886端口，进行MQTT连接，然后监听具体的Topic实现自己的逻辑。\n" +
            "\n" +
            "## MQTT\n" +
            "\n" +
            "Topic命名规则\n" +
            "---\n" +
            "\n" +
            "#### 服务器端订阅\n" +
            "\n" +
            "**服务器端订阅（多数由终端发出） “venus/{firstCmd}/{subCmd}” 为topic名**，接收所有终端上传的数据。\n" +
            "\n" +
            "##### 其中：\n" +
            "\n" +
            "- venus 是固定的开头\n" +
            "- firstCmd 和 subCmd 是 Topic 上的路径，不同的消息有不同，需要根据具体的消息而定。\n" +
            "\n" +
            "<br>\n" +
            "\n" +
            "#### 终端订阅\n" +
            "\n" +
            "**终端订阅（多数由服务器发出） “venus/{firstCmd}/{subCmd}/{object}”**，接收由服务器\n" +
            "\n" +
            "##### 其中：\n" +
            "\n" +
            "- venus 是固定的开头\n" +
            "- firstCmd 和 subCmd 是 Topic 上的路径，不同的消息有不同，需要根据具体的消息而定。\n" +
            "- object是特定的对象，可能是设备，可能是会议室等，根据具体的消息而定。\n" +
            "\n" +
            "<br>\n" +
            "\n" +
            "Payload结构\n" +
            "---\n" +
            "MQTT具体的报文内容如下，根据不同的消息有不同的报文内容，整体结构分为上行的报文和下行的报文。\n" +
            "\n" +
            "\n" +
            "### 上行报文\n" +
            "~~~\n" +
            "{\n" +
            "    \"head\":\"gonsin\",\n" +
            "    \"terminal\":{\n" +
            "        \"uuid\":\"xxxx\"\n" +
            "        \"version\":\"1.2.0\"\n" +
            "        \"host\":\"30000\"\n" +
            "    },\n" +
            "    \"cmd\":{\n" +
            "        \"firstcmd\":\"xxxx\",\n" +
            "        \"subcmd\":\"xxxx\",\n" +
            "        \"response\":0\n" +
            "    },\n" +
            "    \"args\":{\n" +
            "        // 根据各种指令不同内容\n" +
            "    }\n" +
            "}\n" +
            "~~~\n" +
            "\n" +
            "#### 结构解释\n" +
            "|参数名| 参数含义                |是否必填|例子|\n" +
            "|-|---------------------|-|-|\n" +
            "|head| 固定为gonsin           |是|gonsin\n" +
            "|terminal| 终端主机信息              |否|\n" +
            "| - uuid| 设备的UUID，用于反向发送数据    |是|AB65DC239A90\n" +
            "| - version| 主机版本号               |否|1.0.0|\n" +
            "| - server| 主机类型                |否|\n" +
            "|cmd| 指令的结构               |是\n" +
            "| - firstcmd| 第一指令名称              |是|micctrl\n" +
            "| - subcmd| 次级指令名称              |是|on|\n" +
            "| - response| 该消息是否为回应（目前固定为1）    |是|0|\n" +
            "|args| 根据不同的消息有不同内容传递不同的内容 |否|\n" +
            "\n" +
            "<br>\n" +
            "\n" +
            "\n" +
            "\n" +
            "### 下行报文\n" +
            "~~~\n" +
            "{\n" +
            "    \"head\":\"gonsin\",\n" +
            "    \"cmd\":{\n" +
            "        \"firstcmd\":\"xxxx\",\n" +
            "        \"subcmd\":\"xxxx\",\n" +
            "        \"response\":0\n" +
            "    },\n" +
            "    \"args\":{\n" +
            "        // 根据各种指令不同内容\n" +
            "    }\n" +
            "}\n" +
            "~~~\n" +
            "\n" +
            "#### 结构解释\n" +
            "|参数名| 参数含义                |是否必填|例子|\n" +
            "|-|---------------------|-|-|\n" +
            "|head| 固定为gonsin           |是|gonsin\n" +
            "|cmd| 指令的结构               |是\n" +
            "| - firstcmd| 第一指令名称              |是|micctrl\n" +
            "| - subcmd| 次级指令名称              |是|on|\n" +
            "| - response| 该消息是否为回应（目前固定为1）    |是|0|\n" +
            "|args| 根据不同的消息有不同内容传递不同的内容 |否|\n" +
            "\n" +
            "<br>";
}
